{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 彩色图片直方图\n",
    "\n",
    "最重要的图像美化效果是直方图均衡化，直方图分为灰度图的直方图和彩色图的直方图两种，彩色图片有RGB三种颜色的直方图。  \n",
    "可以通过直方图均衡化使图像的直方图分布更均匀，经过直方图均衡化后，图片的亮度和清晰度的效果会更好。\n",
    "\n",
    "直方图中横坐标表示0-255的颜色等级，纵坐标是每个颜色等级在整张图片中出现的概率(0-1)，即通常是归一化后的直方图。\n",
    "\n",
    "<img src='images/直方图.jpg' width=50%>\n",
    "\n",
    "[说说直方图均衡化](https://zhuanlan.zhihu.com/p/32857009)\n",
    "\n",
    "直方图是很多空间域图像处理技术的基础，可以有效的用于图像增加，图像压缩与分割等各个方面。\n",
    "* 在较暗的图中，直方图的组成成分集中在灰度级低的一侧\n",
    "* 在比较亮的图中，直方图的组成成分集中在了灰度级高的一侧\n",
    "* 在低对比度的图中，直方图窄而且集中在中间的区域\n",
    "* 在高对比度的图中，直方图覆盖了灰度级很宽的范围，而且像素的分布比较均匀\n",
    "\n",
    "如果要从美学的角度调整一幅灰度图，要尽可能保证该图像的直方图能覆盖全部的灰度等级并且分布均匀，那么图像就有了高对比度和多变的灰度色调。  \n",
    "直方图的均衡化，是一种变换函数使得其对原图进行变换后，得到的新图像能够满足上面所说的直方图的分布要求。\n",
    "\n",
    "\n",
    "主要函数：cv2.calcHist(), np.histogram()  \n",
    "原理：通过直方图可以对整幅图像的对比度，亮度，灰度分布等有一个直观的认识。直方图的X轴是灰度值（0,255），Y轴是图片中每个灰度值对应的像素数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "def ImageHist(image,type): # 直方图的统计\n",
    "    color = (255,255,255)\n",
    "    windowName = 'Gray'\n",
    "    if type == 31: # blue\n",
    "        color = (255,0,0)\n",
    "        windowName = 'B Hist'\n",
    "    elif type == 32: # green\n",
    "        color = (0,255,0)\n",
    "        windowName = 'G Hist'\n",
    "    elif type == 33: # red\n",
    "        color = (0,0,255)\n",
    "        windowName = 'R Hist'\n",
    "\n",
    "    # 计算图片的直方图：\n",
    "    # 1 image 2 直方图通道,[0]表示灰度直方图 4 直方图的柱状数 5 灰度值范围0-255\n",
    "    hist = cv2.calcHist([image], [0], None, [256], [0.0,255.0])\n",
    "    # print(hist.shape) # (256, 1)\n",
    "    # 计算当前直方图中最大值和最小值以及对应的下标\n",
    "    minV, maxV, minL, maxL = cv2.minMaxLoc(hist)\n",
    "    # 创建画布\n",
    "    histImg = np.zeros([256,256,3], np.uint8) # 彩色图\n",
    "    for h in range(256): # 对于每个灰度等级(0-255)\n",
    "        intenNormal = int(hist[h]*256/maxV) # 归一化数组\n",
    "        cv2.line(histImg, (h,256), (h,256-intenNormal), color)\n",
    "    cv2.imshow(windowName, histImg)\n",
    "\n",
    "    return histImg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(547, 730, 3)\n",
      "(3, 547, 730)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img = cv2.imread('image0.jpg',1)\n",
    "# cv2.imshow('src', img)\n",
    "\n",
    "channels = cv2.split(img)# BGR - B G R\n",
    "print(img.shape)\n",
    "print(np.array(channels).shape)\n",
    "\n",
    "for i in range(len(channels)):\n",
    "    ImageHist(channels[i], 31+i)\n",
    "cv2.waitKey(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "无需分离通道，用折线来描绘直方图的边界可在一副图中同时绘制三个通道的直方图\n",
    "\n",
    "[直方图的计算与显示](https://blog.csdn.net/sunny2038/article/details/9097989)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import cv2  \n",
    "import numpy as np  \n",
    "\n",
    "img = cv2.imread('image0.jpg', 1)  \n",
    "h = np.zeros((256,256,3)) #创建用于绘制直方图的全0图像  \n",
    "\n",
    "bins = np.arange(256).reshape(256,1) #保存直方图中各bin的顶点位置  \n",
    "color = [(255,0,0),(0,255,0),(0,0,255)] #BGR三种颜色  \n",
    "for ch, col in enumerate(color):  \n",
    "    originHist = cv2.calcHist([img],[ch],None,[256],[0,256])  \n",
    "    cv2.normalize(originHist, originHist, 0, 255*0.9, cv2.NORM_MINMAX)  \n",
    "    hist=np.int32(np.around(originHist))  \n",
    "    pts = np.column_stack((bins,hist))  \n",
    "    cv2.polylines(h,[pts],False,col)  \n",
    "\n",
    "h=np.flipud(h)  \n",
    "\n",
    "cv2.imshow('colorhist',h)  \n",
    "cv2.waitKey(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 直方图均衡化（API）\n",
    "\n",
    "对RGB图像进行直方图均衡化会改变图像的整体颜色，如果直方图均衡化后不想改变整体的颜色，而只是进行亮度增强或直方图离散化，可以采用**YUV**的形式，只把Y通道进行直方图离散化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#灰度 直方图均衡化\n",
    "import cv2\n",
    "import numpy as np\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "cv2.imshow('src',gray)\n",
    "dst = cv2.equalizeHist(gray) # 直方图均衡化\n",
    "cv2.imshow('dst',dst)\n",
    "cv2.waitKey(0)\n",
    "\n",
    "# 图像经过直方图均衡化后，灰度图更加明亮"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#彩色 直方图均衡化\n",
    "import cv2\n",
    "import numpy as np\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "cv2.imshow('src',img)\n",
    "(b,g,r) = cv2.split(img) # 通道分解\n",
    "# equalizeHist()只能传入单通道\n",
    "bH = cv2.equalizeHist(b)\n",
    "gH = cv2.equalizeHist(g)\n",
    "rH = cv2.equalizeHist(r)\n",
    "result = cv2.merge((bH,gH,rH)) # 通道合成\n",
    "cv2.imshow('dst',result)\n",
    "cv2.waitKey(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3, 547, 730)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#YUV 直方图均衡化\n",
    "import cv2\n",
    "import numpy as np\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "imgYUV = cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb) # 转换为YUV\n",
    "cv2.imshow('src',img)\n",
    "\n",
    "channelYUV = cv2.split(imgYUV)\n",
    "print(np.array(channelYUV).shape)\n",
    "channelYUV[0] = cv2.equalizeHist(channelYUV[0])\n",
    "channels = cv2.merge(channelYUV)\n",
    "\n",
    "# 也可以不拆分，直接将Y通道值均衡化\n",
    "# imgYUV[:,:,0] = cv2.equalizeHist(imgYUV[:,:,0])\n",
    "\n",
    "result = cv2.cvtColor(channels, cv2.COLOR_YCrCb2BGR)\n",
    "cv2.imshow('dst',result)\n",
    "cv2.waitKey(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 灰度直方图\n",
    "\n",
    "本质：统计每个像素灰度出现的概率p，横坐标是0-255，纵坐标是概率p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x23aa7b2d0b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "imgInfo = img.shape\n",
    "height = imgInfo[0]\n",
    "width = imgInfo[1]\n",
    "gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "count = np.zeros(256, np.float) # 记录每个灰度值出现的个数\n",
    "\n",
    "# for i in range(0, height):\n",
    "#     for j in range(0, width):\n",
    "#         pixel = gray[i,j]\n",
    "#         index = int(pixel)\n",
    "#         count[index] = count[index]+1\n",
    "# for i in range(0,256):\n",
    "#     count[i] = count[i]/(height*width)\n",
    "\n",
    "keys = np.unique(gray)\n",
    "for key in keys:\n",
    "    count[key] = np.sum(gray==key)\n",
    "\n",
    "prob = count / (height*width) # 求得概率\n",
    "x = np.linspace(0, 255, 256)\n",
    "plt.figure()\n",
    "# 1 横坐标 2 纵坐标 3 线宽 4 透明度\n",
    "plt.bar(x, prob, 0.9, alpha=1, color='gray')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 彩色直方图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x23aabb8a5f8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "imgInfo = img.shape\n",
    "height = imgInfo[0]\n",
    "width = imgInfo[1]\n",
    "\n",
    "count_b = np.zeros(256, np.float)\n",
    "count_g = np.zeros(256, np.float)\n",
    "count_r = np.zeros(256, np.float)\n",
    "\n",
    "# for i in range(0,height):\n",
    "#     for j in range(0,width):\n",
    "#         (b,g,r) = img[i,j]\n",
    "#         index_b = int(b)\n",
    "#         index_g = int(g)\n",
    "#         index_r = int(r)\n",
    "#         count_b[index_b] = count_b[index_b]+1\n",
    "#         count_g[index_g] = count_g[index_g]+1\n",
    "#         count_r[index_r] = count_r[index_r]+1\n",
    "# for i in range(0,256):\n",
    "#     count_b[i] = count_b[i]/(height*width)\n",
    "#     count_g[i] = count_g[i]/(height*width)\n",
    "#     count_r[i] = count_r[i]/(height*width)\n",
    "\n",
    "(b,g,r) = cv2.split(img)\n",
    "keys = np.arange(256)\n",
    "for key in keys:\n",
    "    count_b[key] = np.sum(b==key)\n",
    "    count_g[key] = np.sum(g==key)\n",
    "    count_r[key] = np.sum(r==key)\n",
    "prob_b = count_b / (height*width)\n",
    "prob_g = count_g / (height*width)\n",
    "prob_r = count_r / (height*width)\n",
    "\n",
    "x = np.linspace(0,255,256)\n",
    "fig = plt.figure(figsize=(16,5)) # 幕布\n",
    "ax1 = fig.add_subplot(1,3,1)\n",
    "ax1.bar(x,prob_b,0.9,alpha=1,color='b')\n",
    "ax2 = fig.add_subplot(1,3,2)\n",
    "ax2.bar(x,prob_g,0.9,alpha=1,color='g')\n",
    "ax3 = fig.add_subplot(1,3,3)\n",
    "ax3.bar(x,prob_r,0.9,alpha=1,color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 灰度直方图均衡化\n",
    "\n",
    "在直方图中纵坐标表示每个灰度等级对应的概率。\n",
    "```python\n",
    "灰度等级  概率  累积概率\n",
    "1         0.02   0.02\n",
    "2         0.01   0.03\n",
    "3         0.03   0.06\n",
    "...\n",
    "```\n",
    "\n",
    "累积概率就是加上之前所有灰度等级的概率，256个灰度等级，每个灰度等级都会有一个概率和一个累积概率。值越大的像素累积概率越高。  \n",
    "比如灰度值为100的像素的累计概率为0.5，就用255\\*0.5代替该像素这个值，其他灰度等级的像素都按照这种方式进行更新，就可以实现直方图的均衡化。\n",
    "\n",
    "对一幅图像做一次直方图均衡化，和做多次的结果是一样的。  \n",
    "一幅图像只能对应一个直方图，但是一个直方图可以对应多幅图像，这说明了直方图和图像的像素位置没有直接的关系，只是统计了在一个灰度级出现的像素个数的多少，并不知道这些像素值具体分布在这张图像上的什么位置。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x23aa7d11fd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 1 统计每个颜色出现的概率 2 累计概率 3 0-255 255*p 4 new pixel\n",
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 统计每个灰度值出现的概率\n",
    "def pixel_num(gray):\n",
    "    count = np.zeros(256, np.float)\n",
    "\n",
    "     # 计算每个灰度等级的概率\n",
    "    keys = np.unique(gray)\n",
    "    for key in keys:\n",
    "        count[key] = np.sum(gray==key)\n",
    "    probs = count / (height*width)\n",
    "    return probs\n",
    "\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "imgInfo = img.shape\n",
    "height = imgInfo[0]\n",
    "width = imgInfo[1]\n",
    "gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "cv2.imshow('src',gray)\n",
    "\n",
    "probs = pixel_num(gray)\n",
    "\n",
    "#计算累计概率\n",
    "prob_sum = np.zeros(256, np.float)\n",
    "for i in range(0,256):\n",
    "    prob_sum[i] = np.sum(probs[:i+1])\n",
    "# for i in range(1,256):\n",
    "#     prob_sum[i] = prob_sum[i-1]+probs[i]\n",
    "\n",
    "# 计算映射表\n",
    "map_table = (prob_sum * 255).astype(np.uint8)\n",
    "\n",
    "# 映射\n",
    "for i in range(0,height):\n",
    "    for j in range(0,width):\n",
    "        pixel = gray[i,j]\n",
    "        gray[i,j] = map_table[pixel]\n",
    "\n",
    "probs2 = pixel_num(gray)\n",
    "\n",
    "fig = plt.figure(figsize=(12,4)) # 幕布\n",
    "x = np.linspace(0,255,256)\n",
    "ax1 = fig.add_subplot(1,2,1) # 选取幕布的前半部分\n",
    "ax1.bar(x, probs, 0.9, alpha=1, color='gray')\n",
    "ax2 = fig.add_subplot(1,2,2)\n",
    "ax2.bar(x, probs2, 0.9, alpha=1, color='gray')\n",
    "plt.show()\n",
    "\n",
    "cv2.imshow('dst',gray)\n",
    "cv2.waitKey(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 彩色直方图均衡化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x23aad748cf8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x23aa96b1160>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def pixel_num(img):\n",
    "    count_b = np.zeros(256,np.float)\n",
    "    count_g = np.zeros(256,np.float)\n",
    "    count_r = np.zeros(256,np.float)\n",
    "\n",
    "    # 计算每个通道中每个等级的概率\n",
    "    (b,g,r) = cv2.split(img)\n",
    "    keys = np.arange(256)\n",
    "    for key in keys:\n",
    "        count_b[key] = np.sum(b==key)\n",
    "        count_g[key] = np.sum(g==key)\n",
    "        count_r[key] = np.sum(r==key)\n",
    "    probs_b = count_b / (height*width)\n",
    "    probs_g = count_g / (height*width)\n",
    "    probs_r = count_r / (height*width)\n",
    "    return probs_b, probs_g, probs_r\n",
    "\n",
    "img = cv2.imread('image0.jpg',1)\n",
    "cv2.imshow('src',img)\n",
    "imgInfo = img.shape\n",
    "height = imgInfo[0]\n",
    "width = imgInfo[1]\n",
    "\n",
    "probs_b, probs_g, probs_r = pixel_num(img)\n",
    "\n",
    "# 计算累计概率\n",
    "prob_sum_b = np.zeros(256, np.float)\n",
    "prob_sum_g = np.zeros(256, np.float)\n",
    "prob_sum_r = np.zeros(256, np.float)\n",
    "for i in range(0,256):\n",
    "    prob_sum_b[i] = np.sum(probs_b[:i+1])\n",
    "    prob_sum_g[i] = np.sum(probs_g[:i+1])\n",
    "    prob_sum_r[i] = np.sum(probs_r[:i+1])\n",
    "\n",
    "# 计算映射表\n",
    "map_b = (prob_sum_b * 255).astype(np.uint8)\n",
    "map_g = (prob_sum_g * 255).astype(np.uint8)\n",
    "map_r = (prob_sum_r * 255).astype(np.uint8)\n",
    "\n",
    "# 映射\n",
    "dst = np.zeros((height,width,3),np.uint8)\n",
    "for i in range(0,height):\n",
    "    for j in range(0,width):\n",
    "        (b,g,r) = img[i,j]\n",
    "        dst[i,j] = (map_b[b],map_g[g],map_r[r])\n",
    "\n",
    "probs2_b, probs2_g, probs2_r = pixel_num(dst)\n",
    "\n",
    "x = np.linspace(0,255,256)\n",
    "\n",
    "fig = plt.figure(figsize=(16,5))\n",
    "ax1 = fig.add_subplot(1,3,1)\n",
    "ax1.bar(x,probs_b,0.9,alpha=1,color='b')\n",
    "ax2 = fig.add_subplot(1,3,2)\n",
    "ax2.bar(x,probs_g,0.9,alpha=1,color='g')\n",
    "ax3 = fig.add_subplot(1,3,3)\n",
    "ax3.bar(x,probs_r,0.9,alpha=1,color='r')\n",
    "\n",
    "fig = plt.figure(figsize=(16,5))\n",
    "ax1 = fig.add_subplot(1,3,1)\n",
    "ax1.bar(x,probs2_b,0.9,alpha=1,color='b')\n",
    "ax2 = fig.add_subplot(1,3,2)\n",
    "ax2.bar(x,probs2_g,0.9,alpha=1,color='g')\n",
    "ax3 = fig.add_subplot(1,3,3)\n",
    "ax3.bar(x,probs2_r,0.9,alpha=1,color='r')\n",
    "\n",
    "plt.show()\n",
    "\n",
    "cv2.imshow('dst',dst)\n",
    "cv2.waitKey(0)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
